/**********************************************************************
 Copyright (C) 2009 Jaakko Vuori

 This file is part of FlexiWorker.
 For more information, see <http://code.google.com/p/flexi-worker/>

 FlexiWorker is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 FlexiWorker is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with FlexiWorker.  If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/

#include "flexidaemon.h"
#include <QApplication>
#include <QMenu>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QDesktopServices>
#include <QUrl>
#include <QApplication>
#include <QStyle>
#include <QProcess>

#include "idlemonitor.h"

FlexiDaemon::FlexiDaemon(QObject* parent) :
    QObject(parent)
{
    m_trayIcon = new QSystemTrayIcon(this);
    m_trayIcon->setIcon(QIcon(":/images/active.svg"));
    m_trayIcon->setToolTip(tr("Flexi-worker"));

    m_trayIconMenu = new QMenu;

    QAction* quitAction = new QAction(tr("&Quit"), this);
    quitAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical));
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

    QAction* editAction = new QAction(tr("&Edit log"), this);
    editAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOpenButton));
    connect(editAction, SIGNAL(triggered()), this, SLOT(editLog()));

    QAction* viewAction = new QAction(tr("&View log"), this);
    viewAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOpenButton));
    connect(viewAction, SIGNAL(triggered()), this, SLOT(viewLog()));

    m_trayIconMenu->addAction(editAction);
    m_trayIconMenu->addAction(viewAction);
    m_trayIconMenu->addSeparator();
    m_trayIconMenu->addAction(quitAction);
    m_trayIcon->setContextMenu(m_trayIconMenu);

    connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
        this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    m_idleMonitor = new IdleMonitor(this);
    connect(m_idleMonitor, SIGNAL(idle(QDateTime)), this, SLOT(onIdle(QDateTime)));
    connect(m_idleMonitor, SIGNAL(back()), this, SLOT(onBack()));

    qDebug() << "START:" << QDateTime::currentDateTime();
    saveEvent(Start, QDateTime::currentDateTime());

    m_trayIcon->show();
}

FlexiDaemon::~FlexiDaemon()
{
    qDebug() << "END:" << QDateTime::currentDateTime();
    saveEvent(End, QDateTime::currentDateTime());
    delete m_trayIconMenu;
}

void FlexiDaemon::onIdle(QDateTime lastActivityTime)
{
    qDebug() << "IDLE:" << lastActivityTime;
    m_trayIcon->setIcon(QIcon(":/images/idle.svg"));
    saveEvent(Idle, lastActivityTime);
}

void FlexiDaemon::onBack()
{
    qDebug() << "BACK:" << QDateTime::currentDateTime();
    m_trayIcon->setIcon(QIcon(":/images/active.svg"));
    saveEvent(Back, QDateTime::currentDateTime());
}

void FlexiDaemon::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason)
    {
        case QSystemTrayIcon::Unknown:
            //qDebug("QSystemTrayIcon::Unknown");
            break;
        case QSystemTrayIcon::Context:
            //qDebug("QSystemTrayIcon::Context");
            break;
        case QSystemTrayIcon::DoubleClick:
            viewLog();
            //qDebug("QSystemTrayIcon::DoubleClick");
            break;
        case QSystemTrayIcon::Trigger:
            //qDebug("QSystemTrayIcon::Trigger");
            break;
        case QSystemTrayIcon::MiddleClick:
            //qDebug("QSystemTrayIcon::MiddleClick");
            break;
        default:
            break;
    }
}

void FlexiDaemon::saveEvent(Event event, QDateTime dateTime)
{
    QDir homeDir(QDir::home());
    QString dirName = homeDir.absoluteFilePath(".flexi-worker");
    if (!homeDir.exists(dirName))
    {
        homeDir.mkpath(dirName);
    }

    QString fileName = QDir(dirName).absoluteFilePath("flexi-worker.log");
    QFile file(fileName);
    file.open(QIODevice::Append | QIODevice::Text);
    QString line;
    switch (event)
    {
        case Start: line += "START: "; break;
        case End: line += "END: "; break;
        case Idle: line += "IDLE: "; break;
        case Back: line += "BACK: "; break;
        default: break;
    }
    line += dateTime.toString(Qt::ISODate);
    line += "\n";

    file.write(line.toAscii());
    file.close();
}

QString FlexiDaemon::logFileName() const
{
    return QDir(QDir::home().absoluteFilePath(".flexi-worker")).absoluteFilePath("flexi-worker.log");
}


void FlexiDaemon::editLog()
{
    QString url = "file:///" + logFileName();
    QDesktopServices::openUrl(QUrl(url));
}

void FlexiDaemon::viewLog()
{
#ifdef Q_OS_WIN
    QString viewerApp = "flexiviewer";
#else
    QString viewerApp = QDir::toNativeSeparators(QApplication::applicationDirPath() + "/flexiviewer");
#endif
    qDebug() << "trying to launch" << viewerApp;
    bool started = QProcess::startDetached(viewerApp);
    qDebug() << "flexiviewer started: " << started;
}
